<?
/**
 *
 * Copyright (C) 2003-2011 Cory Powers
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 */
require_once('common.php');
require_once('SI_Attachment.php');
require_once('SI_Company.php');
require_once('SI_Expense.php');
require_once('SI_ProjectStatus.php');
require_once('SI_ProjectPriority.php');
require_once('Notify.php');
require_once('SI_SalesCommissionType.php');
define('PROJECT_RIGHT_NONE', 0);
define('PROJECT_RIGHT_VIEW', 1);
define('PROJECT_RIGHT_EDIT', 2);
define('PROJECT_RIGHT_FULL', 3);

////////////////////////////////////////////////////////////
// Code generated by CodeGen (http://uversaconsulting.net).
// Insert custom code where indicated below.
////////////////////////////////////////////////////////////

// SI_Project Class Definition
////////////////////////////////////////////////////////////
class SI_Project{
	var $id, $owner_id, $company_id, $project_status_id,
		$project_priority_id, $name, $description, $due_ts,
		$billable, $issue_tracking, $created_ts, $updated_ts,
		$sales_com, $sales_com_type_id, $sales_com_user_id,
		$company, $status, $priority, $owner, $default_item_code_id;

	var $error;

	var $attachments;

	var $ccs;

	var $_owner;

	var $_company;

	var $_sct;

	var $_sct_user;

	var $_total;

	var $_total_cost;
	
	var $_expenses;

	function SI_Project(){
		$this->error = '';
		$this->id = 0;
		$this->owner_id = 0;
		$this->company_id = 0;
		$this->project_status_id = 0;
		$this->project_priority_id = 0;
		$this->name = '';
		$this->description = '';
		$this->due_ts = 0;
		$this->billable = 'Y';
		$this->issue_tracking = 'Y';
		$this->created_ts = 0;
		$this->updated_ts = 0;
		$this->sales_com = 'N';
		$this->sales_com_type_id = 0;
		$this->sales_com_user_id = 0;
		$this->default_item_code_id = 0;

		$this->company = '';
		$this->status = '';
		$this->priority = '';
		$this->owner = '';
		$this->ccs = array();

		$this->_owner = FALSE;
		$this->_sct = FALSE;
		$this->_sct_user = FALSE;
		$this->_company = FALSE;
		$this->_total = FALSE;
		$this->_total_cost = FALSE;
		$this->_expenses = FALSE;
	}

	function _populateData($values){
		if(is_array($values)){
			$this->id = $values[0];
			$this->owner_id = $values[1];
			$this->company_id = $values[2];
			$this->project_status_id = $values[3];
			$this->project_priority_id = $values[4];
			$this->name = $values[5];
			$this->description = $values[6];
			$this->due_ts = $values[7];
			$this->billable = $values[8];
			$this->issue_tracking = $values[9];
			$this->created_ts = $values[10];
			$this->updated_ts = $values[11];
			$this->sales_com = $values[12];
			$this->sales_com_type_id = $values[13];
			$this->sales_com_user_id = $values[14];

			$this->company = $values[15];
			$this->status = $values[16];
			$this->priority = $values[17];
			$this->owner = $values[18];
		}
	}

	function updateFromAssocArray($array){
		if(is_array($array)){
			foreach($array as $key => $value)
				$this->$key = $value;
		}
	}

	function escapeStrings(){
		global $db_conn;

		$vars = get_object_vars($this);
		foreach($vars as $key => $value){
			if(is_string($value)){
				$this->$key = $db_conn->escapeString($value);
			}
		}
	}

	function stripSlashes(){
		$vars = get_object_vars($this);
		foreach($vars as $key => $value){
			if(is_string($value)){
				$this->$key = stripcslashes($value);
			}
		}
	}

	function getLastError(){
		return $this->error;
	}

	function add(){
		global $db_conn;

		if($this->_updateCommissions() === FALSE)
			return FALSE;

		$this->escapeStrings();
		$result = $db_conn->query("INSERT INTO projects (owner_id, company_id, project_status_id, project_priority_id, ".
			"name, description, due_ts, billable, ".
			"issue_tracking, created_ts,  updated_ts, sales_com, ".
			"sales_com_type_id, sales_com_user_id, default_item_code_id)".
			" VALUES(".$this->owner_id.", ".$this->company_id.", ".$this->project_status_id.", ".$this->project_priority_id.", ".
			"'".$this->name."', '".$this->description."', ".$this->due_ts.", '".$this->billable."', ".
			"'".$this->issue_tracking."', UNIX_TIMESTAMP(), ".$this->updated_ts.", '".$this->sales_com."', ".
			"".$this->sales_com_type_id.", ".$this->sales_com_user_id.", ".$this->default_item_code_id.")");
		$this->stripSlashes();
		if($result){
			$this->id = mysql_insert_id();
			if($this->addUserRight($this->owner_id, PROJECT_RIGHT_FULL) === FALSE)
				return FALSE;
			if($this->addCC($this->owner_id) === FALSE)
				return FALSE;
			return TRUE;
		}else{
			$this->error = "SI_Project::add() : ".$db_conn->getLastError()."\n";
			return FALSE;
		}
	}

	function update(){
		global $db_conn;

		if(!isset($this->id)){
			$this->error = "SI_Project::update() : Project id not set\n";
			return FALSE;
		}

		if($this->_updateCommissions() === FALSE)
			return FALSE;

		$this->escapeStrings();
		$result = $db_conn->query("UPDATE projects SET owner_id = ".$this->owner_id.", ".
			"company_id = ".$this->company_id.", project_status_id = ".$this->project_status_id.", ".
			"project_priority_id = ".$this->project_priority_id.", name = '".$this->name."', ".
			"description = '".$this->description."', due_ts = ".$this->due_ts.", ".
			"billable = '".$this->billable."', issue_tracking = '".$this->issue_tracking."', ".
			"created_ts = ".$this->created_ts.", updated_ts = UNIX_TIMESTAMP(), ".
			"sales_com = '".$this->sales_com."', sales_com_type_id = ".$this->sales_com_type_id.", ".
			"sales_com_user_id = ".$this->sales_com_user_id.", default_item_code_id = ".$this->default_item_code_id.
			" WHERE id = ".$this->id."");
		$this->stripSlashes();
		if($result){
			return TRUE;
		}else{
			$this->error = "SI_Project::update() : ".$db_conn->getLastError()."\n";
			return FALSE;
		}
	}

	function delete($id = NULL){
		global $db_conn;

		if(!isset($id)){
			$id = $this->id;
		}

		if(!isset($id)){
			$this->error = "SI_Project::delete() : Project id not set\n";
			return FALSE;
		}

		$result = $db_conn->query("DELETE FROM projects WHERE id = $id");

		if($result){
			return TRUE;
		}else{
			$this->error = "SI_Project::delete() : ".$db_conn->getLastError()."\n";
			return FALSE;
		}
	}

	function get($id = NULL){
		global $db_conn;

		if(!isset($id)){
			$id = $this->id;
		}

		if(!isset($id)){
			$this->error = "SI_Project::get() : Project id not set\n";
			return FALSE;
		}

		$Project = SI_Project::retrieveSet("WHERE p.id = $id", TRUE);
		if($Project === FALSE){
			return FALSE;
		}

		if(isset($Project[0])){
			$this->updateFromAssocArray($Project[0]);
			if($this->_populateAttachments() === FALSE)
				return FALSE;
			if($this->_populateCCUsers() === FALSE)
				return FALSE;
			$this->stripSlashes();
		}else{
			$this->error = "SI_Project::get() : No data retrieved from query\n";
			return FALSE;
		}
		return TRUE;
	}

	function retrieveSet($clause = '', $raw = FALSE){
		global $db_conn;

		if(!empty($clause)){
			$clause = trim($clause);
			if(strlen($clause) > 5){
				if(strtolower(substr($clause, 0, 5)) != "where" && strtolower(substr($clause, 0, 5)) != "order")
					$clause = "WHERE ".$clause;
			}else{
				$clause = "WHERE ".$clause;
			}
		}

		$result = $db_conn->query("SELECT  p.id, p.owner_id, p.company_id, p.project_status_id, p.project_priority_id, p.name, ".
			"p.description, p.due_ts, p.billable, p.issue_tracking, p.created_ts, p.updated_ts, ".
			"p.sales_com, p.sales_com_type_id, p.sales_com_user_id, default_item_code_id, ".
			"c.name AS company_name, s.name AS status, pri.name AS priority, CONCAT_WS(' ', u.first_name, u.last_name) AS owner_name ".
			"FROM projects AS p ".
			"LEFT JOIN companies AS c ON p.company_id = c.id ".
			"LEFT JOIN project_statuses AS s ON p.project_status_id = s.id ".
			"LEFT JOIN project_priorities AS pri ON p.project_priority_id = pri.id ".
			"LEFT JOIN users AS u ON p.owner_id = u.id ".
			$clause);

		if(!$result){
			$this->error = "SI_Project::retrieveSet(): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		while($row=$result->fetchArray(MYSQL_ASSOC)){
			if($raw == TRUE){
				$Project[] = $row;
			}else{
				$temp =& new SI_Project();
				$temp->updateFromAssocArray($row);
				if($temp->_populateAttachments() === FALSE){
					$this->error = $temp->getLastError();
					return FALSE;
				}
				if($temp->_populateCCUsers() === FALSE){
					$this->error = $temp->getLastError();
					return FALSE;
				}
				$temp->stripSlashes();
				$Project[] =& $temp;
			}

		}
		$result->free();

		return $Project;
	}
// BEGIN - Custom SI_Project methods
////////////////////////////////////////////////////////////
	var $user_rights;

	var $right_level_names = array('NONE','VIEW','EDIT','FULL');

	function addUserRight($user_id, $access){
		global $db_conn;

		if(intval($this->id) <= 0){
			$this->error = "SI_Project::addUserRight($user_id, $access): Project ID not set!";
			return FALSE;
		}

		$sql = 'REPLACE INTO user_project_rights SET level = '.intval($access).',
		 user_id = '.intval($user_id).', project_id = '.intval($this->id);

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::addUserRight($user_id, $access): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		if($this->_populateUserRights() === FALSE)
			return FALSE;

		return TRUE;
	}

	function deleteUserRight($user_id){
		global $db_conn;

		if(intval($this->id) <= 0){
			$this->error = "SI_Project::deleteUserRight($user_id): Project ID not set!";
			return FALSE;
		}

		$sql = 'DELETE FROM user_project_rights
		WHERE user_id = '.intval($user_id).' AND project_id = '.intval($this->id);

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::deleteUserRight($user_id): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		if($this->_populateUserRights() === FALSE)
			return FALSE;

		return TRUE;
	}

	function _populateUserRights(){
		global $db_conn;

		if(intval($this->id) <= 0){
			$this->error = "SI_Project::_populateUserRights(): Project ID not set!";
			return FALSE;
		}

		$sql = 'SELECT project_id, user_id, level FROM user_project_rights
		WHERE project_id = '.intval($this->id);

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::_populateUserRights(): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		$this->user_rights = array();
		while($row = $result->fetchArray(MYSQL_ASSOC)){
			$this->user_rights[$row['user_id']] = $row['level'];
		}

		return TRUE;

	}

	function addCC($user_id){
		global $db_conn;

		if(intval($this->id) <= 0){
			$this->error = "SI_Project::addCC($user_id): Project ID not set!";
			return FALSE;
		}

		$sql = 'REPLACE INTO project_cc SET user_id = '.intval($user_id).', project_id = '.intval($this->id);

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::addCC($user_id): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		if($this->_populateCCUsers() === FALSE)
			return FALSE;

		return TRUE;
	}

	function deleteCC($user_id){
		global $db_conn;

		if(intval($this->id) <= 0){
			$this->error = "SI_Project::deleteCC($user_id): Project ID not set!";
			return FALSE;
		}

		$sql = 'DELETE FROM project_cc
		WHERE user_id = '.intval($user_id).' AND project_id = '.intval($this->id);

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::deleteCC($user_id): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		if($this->_populateCCUsers() === FALSE)
			return FALSE;

		return TRUE;
	}

	function _populateCCUsers(){
		global $db_conn;

		if(intval($this->id) <= 0){
			$this->error = "SI_Project::_populateCCUsers(): Project ID not set!";
			return FALSE;
		}

		$this->ccs = array();

		$sql = 'SELECT user_id FROM project_cc
		WHERE project_id = '.intval($this->id);

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::_populateCCUsers(): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		$ids = array();
		while($row = $result->fetchArray(MYSQL_ASSOC)){
			$ids[] = $row['user_id'];
		}

		if(count($ids) > 0){
			$user = new SI_User();
			$users = $user->retrieveSet("WHERE u.id IN (".implode(', ', $ids).")");
			if($users === FALSE){
				$this->error = "SI_Project::_populateCCUsers(): ".$user->getLastError()."\n";
				return FALSE;
			}
			$this->ccs = $users;
		}

		return TRUE;

	}

	function getUserRights(){
		global $db_conn, $levels;

		if(intval($this->id) <= 0){
			$this->error = "SI_Project::getUserRights(): Project ID not set!";
			return FALSE;
		}

		$sql = 'SELECT project_id, user_id, level, first_name, last_name
		FROM user_project_rights AS rights
		LEFT JOIN users AS u ON rights.user_id = u.id
		WHERE project_id = '.intval($this->id);

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::_populateUserRights(): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		$rights = array();
		while($row = $result->fetchArray(MYSQL_ASSOC)){
			$rights[] = array(
										'user_id' => $row['user_id'],
										'user_name' => $row['first_name'].' '.$row['last_name'],
										'level' => $row['level'],
										'level_name' => $this->right_level_names[$row['level']]
										);
		}

		return $rights;

	}

	function getUserRight($user_id){
		if(!isset($this->user_rights)){
			if($this->_populateUserRights() === FALSE)
				return FALSE;
		}

		if(isset($this->user_rights[$user_id]))
			return $this->user_rights[$user_id];

		return 'NONE';
	}

	function hasRights($level){
		global $loggedin_user;

		if($loggedin_user->hasRight('admin')){
			return TRUE;
		}

		$rights = $this->getUserRight($loggedin_user->id);
		if($rights === FALSE){
			fatal_error('Error getting rights user rights for project: '.$this->getLastError());
			return FALSE;
		}

		if($rights >= $level){
			return TRUE;
		}

		return FALSE;

	}

	function getMyProjects($user_id, $pending_only = TRUE){
		global $db_conn;

		if(intval($user_id) <= 0){
			$this->error =  "SI_Project::getMyProjects(): Invalid user id!\n";
			return FALSE;
		}

		if($pending_only){
			$pending_sql = ' AND s.completed = \'N\' ';
		}else{
			$pending_sql = '';
		}

		$sql = 'SELECT project_id FROM user_project_rights
		WHERE user_id = '.$user_id.' AND level > '.PROJECT_RIGHT_NONE;

		$result = $db_conn->query($sql);
		if($result === FALSE){
			$this->error = "SI_Project::getMyProjects(): ".$db_conn->getLastError()."\n";
			return FALSE;
		}

		$ids = array();
		while($row = $result->fetchArray()){
			$ids[] = $row[0];
		}

		$projects = array();
		if(count($ids) > 0){
			$projects = $this->retrieveSet('WHERE p.id IN ('.implode(',', $ids).')'.$pending_sql.' ORDER BY c.name, p.name');
			if($projects === FALSE)
				return FALSE;
		}

		return $projects;

	}

	function _populateAttachments(){
		$attachment = new SI_Attachment();
		$attachments = $attachment->getAttachmentsForProject($this->id);
		if($attachments === FALSE){
			$this->error = "SI_Project::_populateAttachments(): Error getting attachments:\n".$attachment->getLastError();
			return FALSE;
		}else{
			$this->attachments = $attachments;
		}

		return TRUE;
	}

	function deleteAttachment($attachment_id){
		$attachment = new SI_Attachment();
		if($attachment->delete($attachment_id) === FALSE){
			$this->error = "SI_Project::deleteAttachment($attachment_id): ".$attachment->getLastError()."\n";
			return FALSE;
		}

		if($this->_populateAttachments() === FALSE)
			return FALSE;

		return TRUE;
	}

	function addAttachment($local_file, $filename, $description){
		$attachment = new SI_Attachment();
		$filename = $attachment->save($local_file, $filename);
		if($filename === FALSE){
			$this->error = "SI_Project::addAttachment(): ".$attachment->getLastError()."\n";
			return FALSE;
		}

		$attachment->project_id = $this->id;
		$attachment->description = $description;
		$attachment->path = $filename;
		if($attachment->add() === FALSE){
			$this->error = "SI_Project::addAttachment(): ".$attachment->getLastError()."\n";
			return FALSE;
		}

		if($this->_populateAttachments() === FALSE)
			return FALSE;

		return TRUE;
	}

	function isDiff($old, $new = NULL){
		if(!isset($new)){
			$new =& $this;
		}

		$fields = array(
			'id', 'owner_id', 'company_id', 'project_status_id',
			'project_priority_id', 'name', 'description', 'due_ts',
			'billable', 'issue_tracking', 'status',	'priority'
			);

		foreach($fields as $field){
			if($old->$field != $new->$field){
				return TRUE;
			}
		}

		return FALSE;
	}

	function getNotificationParams($activities = array()){
		global $loggedin_user;

		$params = array();
		$fields = array(
			'id', 'owner_id', 'company_id', 'project_status_id',
			'project_priority_id', 'name', 'description', 'due_ts',
			'billable', 'issue_tracking', 'status',
			'priority', 'created_ts', 'updated_ts'
			);

		foreach($fields as $field){
			$params[$field] = $this->$field;
		}

		if(is_a($this->owner, 'SI_User')){
			$params['owner_first_name'] = $this->owner->first_name;
			$params['owner_last_name'] = $this->owner->last_name;
			$params['owner_email'] = $this->owner->email;
		}

		if(is_a($loggedin_user, 'SI_User')){
			$params['updater_first_name'] = $loggedin_user->first_name;
			$params['updater_last_name'] = $loggedin_user->last_name;
			$params['updater_email'] = $loggedin_user->email;
			$user_name = $loggedin_user->first_name.' '.$loggedin_user->last_name;
		}

		if(empty($user_name)) $user_name = "Anonymous";
		$params['activities'] = "$user_name made the following changes on ".date("D M jS, Y \a\\t h:i:s A")."\n";
		if(is_array($activities) && count($activities) > 0){
			foreach($activities as $activity){
				$params['activities'] .= "$activity\n";
			}
		}

		if(is_a($this->company, 'SI_Company')){
			$params['company_name'] = $this->company->name;
		}

		if(is_array($this->ccs) && is_a($this->ccs[0], 'SI_User')){
			$params['project_ccs'] = array();
			foreach($this->ccs as $cc){
				$params['project_ccs'][] = $cc->email;
			}
		}

		return $params;
	}

	function sendUpdateNotification($activities = array()){
		$notif = new Notification();
		$params = $this->getNotificationParams($activities);
		if(!isset($params['project_ccs']) || empty($params['project_ccs']))
			return TRUE;
			
		if($notif->getByName('ProjectUpdated') === FALSE){
			$this->error = "SI_Project::update() : ".$notif->getLastError()."\n";
			return FALSE;
		}
		if($notif->prepare($params) === FALSE){
			$this->error = "SI_Project::update() : ".$notif->getLastError()."\n";
			return FALSE;
		}
		if($notif->send() === FALSE){
			$this->error = "SI_Project::update() : ".$notif->getLastError()."\n";
			return FALSE;
		}

		return TRUE;
	}

	function _updateCommissions(){
		if($this->sales_com == 'N'){
			$this->sales_com_type_id = 0;
			$this->sales_com_user_id = 0;
		}

		return TRUE;
	}

	function getCompany(){
		if($this->_company == FALSE && $this->company_id > 0){
			$company = new SI_Company();
			if($company->get($this->company_id) === FALSE){
				$this->error = "SI_Project::getCompany(): Error getting company: ".$company->getLastError();
				return FALSE;
			}
			$this->_company =& $company;
		}

		return $this->_company;
	}

	function getOwner(){
		if($this->_owner == FALSE && $this->owner_id > 0){
			$owner = new SI_User();
			if($owner->get($this->owner_id) === FALSE){
				$this->error = "SI_Project::getOwner(): Error getting owner: ".$owner->getLastError();
				return FALSE;
			}
			$this->_owner =& $owner;
		}

		return $this->_owner;
	}

	function getSalesCommissionType(){
		if($this->_sct == FALSE){
			$sct = new SI_SalesCommissionType();
			if($this->sales_com == 'Y' && $this->sales_com_type_id > 0){
				if($sct->get($this->sales_com_type_id) === FALSE){
					$this->error = "SI_Project::getSalesCommissionType(): Error getting sales commission: ".$sct->getLastError();
					return FALSE;
				}
				$this->_sct = $sct;
			}elseif($this->sales_com == 'N'){
				$this->_sct = $sct;
			}else{
				$this->error = "SI_Project::getSalesCommissionType(): Invalid sales commission setting: {$this->sales_com}";
				return FALSE;
			}
		}

		return $this->_sct;
	}

	function getSalesCommissionUser(){
		if($this->_sct_user == FALSE){
			$sct_user = new SI_User();
			if($this->sales_com == 'Y' && $this->sales_com_user_id > 0){
				if($sct_user->get($this->sales_com_user_id) === FALSE){
					$this->error = "SI_Project::getSalesCommissionUser(): Error getting sales commission user: ".$sct_user->getLastError();
					return FALSE;
				}
				$this->_sct_user = $sct_user;
			}elseif($this->sales_com == 'N'){
				$this->_sct_user = $sct_user;
			}else{
				$this->error = "SI_Project::getSalesCommissionUser(): Invalid sales commission setting: {$this->sales_com}";
				return FALSE;
			}
		}

		return $this->_sct_user;
	}

	function isBillable(){
		$retval = FALSE;
		if($this->billable == 'Y'){
			$retval = TRUE;
		}elseif($this->billable == 'S'){
			$retval = FALSE;
		}elseif($this->billable == 'N'){
			$retval = FALSE;
		}

		return $retval;
	}

	function isSpec(){
		$retval = FALSE;
		if($this->billable == 'S'){
			$retval = TRUE;
		}

		return $retval;
	}

	function hasCommission(){
		$retval = FALSE;
		if($this->sales_com == 'Y'){
			$retval = TRUE;
		}elseif($this->sales_com == 'N'){
			$retval = FALSE;
		}

		return $retval;
	}

	function getCompanyProjects($company_id, $active = TRUE){
		$company_id = intval($company_id);
		if($active){
			$clause = "WHERE p.company_id = $company_id AND s.completed = 'N'";
		}else{
			$clause = "WHERE p.company_id = $company_id";
		}

		return $this->retrieveSet($clause);
	}

	function getTotal(){
		global $db_conn;

		$this->id = intval($this->id);
		if($this->_total === FALSE && $this->id > 0){
			$sql = "
SELECT SUM(amount) AS amount FROM tasks
LEFT JOIN projects ON tasks.project_id = projects.id
WHERE project_id = {$this->id} AND
((projects.billable = 'S' AND tasks.billable = 'D') OR
(tasks.billable = 'S'))
			";
			$result = $db_conn->query($sql);
			if($result === FALSE){
				$this->error = "SI_Project::getTotal(): Error getting total: ".$db_conn->getLastError();
				return FALSE;
			}

			while($row = $result->fetchArray(MYSQL_ASSOC)){
				$this->_total = $row['amount'];
			}
		}

		return $this->_total;
	}

	function getTotalCost(){
		global $db_conn;

		$this->id = intval($this->id);
		if($this->_total_cost === FALSE && $this->id > 0){
			$sql = "
SELECT SUM(ROUND(((a.end_ts - a.start_ts) / 60 / 60) * a.hourly_rate, 2)) AS amount
FROM task_activities AS a
LEFT JOIN tasks AS t ON a.task_id = t.id
LEFT JOIN projects AS p ON t.project_id = p.id
WHERE p.id = {$this->id}
			";
			$result = $db_conn->query($sql);
			if($result === FALSE){
				$this->error = "SI_Project::getTotalCost(): Error getting total cost: ".$db_conn->getLastError();
				return FALSE;
			}

			while($row = $result->fetchArray(MYSQL_ASSOC)){
				$this->_total_cost = $row['amount'];
			}
		}

		return $this->_total_cost;
	}

	function getExpenses($unbilled = FALSE){
		$exp = new SI_Expense();
		$expenses = $exp->getForProject($this->id, $unbilled);
		if($expenses === FALSE){
			$this->error = "SI_Project::getExpenses(): " . $exp->getLastError();
			return FALSE;
		}
		
		return $expenses;
	}

	/**
	 * Method to retreive option tags for all projects
	 * 
	 * If a company_id is provided this will on provide a
	 * list of projects for the provided company_id
	 *
	 * This method will provide a string that contains
	 * the HTML option tags for all projects in the 
	 * database sorted by Project Name.
	 * 
	 * If a project id is provided in the $selected
	 * argument, then that option tag will be marked
	 * as selected.
	 *
	 * @global DBConn Database access object
	 * @access public
	 * @static
	 * @see getLastError()
	 * @return string|FALSE HTML option tags or FALSE on error
	 */
	function getSelectTags($selected = NULL, $company_id = 0){
		global $db_conn;
		
		$company_id = intval($company_id);
		$company_sql = '';
		if($company_id > 0){
			$company_sql = "WHERE company_id = $company_id";	
		}

		$result = $db_conn->query("SELECT id, name FROM projects $company_sql ORDER BY name");

		if($result === FALSE){
			$this->error = "SI_Project::getSelectTags(): ".$db_conn->getLastError()."\n";
			return FALSE;
		}


		while($row=$result->fetchRow()){
			$sel_text = "";
			if($row[0]==$selected)
				$sel_text = " SELECTED";
			$tags .= "<OPTION VALUE=\"".$row[0]."\"".$sel_text.">".$row[1]."</OPTION>\n";
		}
		return $tags;
	}
	
// END - Custom SI_Project methods
////////////////////////////////////////////////////////////
}

